let source_uri = "http://code.google.com/p/castling/source/browse/trunk/grammers/c/";;

let read_all filename = (
	let f = open_in_bin filename in
	let size = in_channel_length f in
	let result = String.make size '\x00' in
	really_input f result 0 size;
	close_in f;
	result
);;

module Scanner = Scanner.Scanner(Stream);;

let pp_position f (filename, line) = (
	Format.pp_print_string f filename;
	Format.pp_print_string f ":";
	Format.pp_print_int f line;
);;

open Web;;

header_content_type print_string content_type_html;;
header_break print_string;;

begin try (
	print_string "<html>";
	print_string "<head>";
	print_string "<title>";
	encode_entity print_string "Tiny C parser test - Castling demo";
	print_string "</title>";
	print_string "</head>";
	print_string "<body>";
	if post () then (
		let input = read_input () in
		let source = StringMap.find "source" input in
		print_string "<form method=\"post\">";
		print_string "<div>";
		encode_entity print_string "Your source code:";
		print_string "</div>";
		print_string "<div>";
		print_string "<textarea name=\"source\" rows=10 cols=80>";
		encode_entity print_string source;
		print_string "</textarea>";
		print_string "</div>";
		print_string "<div>";
		encode_entity print_string "Parsed result:";
		print_string "</div>";
		print_string "<div>";
		print_string "<textarea rows=10 cols=80>";
		let s = Scanner.create ~objc:true ~cpp:true "post.c" (Stream.of_string source) in
		let p = Parser.create () in
		let rec loop p = (
			let t, pos = Scanner.next s in
			let p = Parser.post pos t p in
			if t <> Lexical.Token.Eof then loop p else p
		) in 
		let p = loop p in
		let pp_elt = Lexical.Token.pp ~paren:true ~quali:false in
		Parser.pp_option (Parser.pp_result pp_elt pp_position) ~paren:false Format.str_formatter (Parser.result p);
		Format.pp_print_newline Format.str_formatter ();
		encode_entity print_string (Format.flush_str_formatter ());
		print_string "</textarea>";
		print_string "</div>";
		print_string "<div>";
		encode_entity print_string "Detected errors:";
		print_string "</div>";
		print_string "<div>";
		print_string "<textarea rows=10 cols=80>";
		let es = List.rev (Parser.errors p) in
		List.iter (fun (pos, error) ->
			let f = Format.str_formatter in
			pp_position f pos;
			Format.pp_print_string f " ";
			Parser.pp_error (Lexical.Token.pp ~paren:true ~quali:false) f error;
			Format.pp_print_newline f ();
			encode_entity print_string (Format.flush_str_formatter ());
		) es;
		print_string "</textarea>";
		print_string "</div>";
		print_string "<div>";
		print_string "<input type=submit value=\"Re-parse!\" />";
		print_string "</div>";
		print_string "</form>"
	) else (
		print_string "<form method=\"post\">";
		print_string "<div>";
		encode_entity print_string "Please, input source code:";
		print_string "</div>";
		print_string "<div>";
		print_string "<textarea name=\"source\" rows=25 cols=80>";
		encode_entity print_string (read_all "example1.ada");
		print_string "</textarea>";
		print_string "</div>";
		print_string "<div>";
		print_string "<input type=submit value=\"Parse!\" />";
		print_string "</div>";
		print_string "</form>"
	);
	print_string "<a href=\"";
	encode_uri print_string source_uri;
	print_string "\">";
	encode_entity print_string "View source code of this parser.";
	print_string "</a>";
	print_string "</body>";
	print_string "</html>"
) with exn -> 
	print_string "----------<br />";
	encode_entity print_string (Printexc.to_string exn);
	print_string "<br />----------\n";
end;;
